﻿using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;

namespace O1.Kernel
{
    [ContractVerification(true)]
    [StructLayout(LayoutKind.Explicit)]
    internal struct DeltaRecord
    {
        public const int Size = Sz.CLR.Int64 + Sz.CLR.Int32;

        [FieldOffset(0)]
        public readonly ulong TransactionId;

        [FieldOffset(Sz.CLR.Int64)]
        public readonly int DataSize;

        public DeltaRecord(ulong transactionId, int dataSize)
            : this()
        {
            this.TransactionId = transactionId;
            this.DataSize = dataSize;
        }

        internal static unsafe DeltaRecord Read(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                return *((DeltaRecord*)p);
            }
        }

        internal unsafe void Write(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                *((DeltaRecord*)p) = this;
            }
        }
    }
}
